{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [],
   "source": [
    "import requests\n",
    "import json\n",
    "from datetime import datetime\n",
    "import pandas as pd\n",
    "import matplotlib.pyplot as plt\n",
    "import numpy as np"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 214,
   "metadata": {},
   "outputs": [],
   "source": [
    "class Asset():\n",
    "    def __init__(self, isin):\n",
    "        self.isin = isin\n",
    "\n",
    "    def _xetra_history(self, start_date, end_date, periode='day'):\n",
    "        df = pd.DataFrame(pd.bdate_range(start_date, end_date, freq='B'), columns=['date'])\n",
    "        df.set_index('date', inplace=True)\n",
    "\n",
    "        limit = (datetime.strptime(end_date, '%Y-%m-%d').year - \\\n",
    "                 datetime.strptime(start_date, '%Y-%m-%d').year+1)*253\n",
    "\n",
    "        api_url = 'https://api.boerse-frankfurt.de/data/price_history?limit='+str(limit)+ \\\n",
    "                '&offset=0&isin=' + str(self.isin) + '&mic=XETR&minDate='+ \\\n",
    "                str(start_date)+'&maxDate='+str(end_date)\n",
    "        \n",
    "        req = requests.get(api_url)\n",
    "        json_data = req.json()['data']\n",
    "            \n",
    "        df_prices = pd.DataFrame(json_data)\n",
    "        df_prices.set_index('date', inplace=True)\n",
    "        df_prices.sort_index(inplace=True)\n",
    "            \n",
    "        df = pd.merge(df, df_prices, how='left', left_index=True, right_index=True)\n",
    "        df.dropna(how='all', inplace=True)          \n",
    "        return df\n",
    "    \n",
    "    \n",
    "    def _langschwarz_history(self, start_date, end_date, periode):\n",
    "        pass\n",
    "        \n",
    "        \n",
    "    def hist_prices(self, start_date, end_date, periode='day', data_source='xetra'):\n",
    "        if data_source == 'xetra':\n",
    "            return self._xetra_history(start_date, end_date)\n",
    "        \n",
    "        if data_source == 'langschwarz':\n",
    "            return self._langschwarz_history(start_date, end_date)\n",
    "       \n",
    "    \n",
    "    def get_ticker(self, start_time='08:00', end_time='22:00'):\n",
    "        today_date = datetime.today().strftime('%Y-%m-%d')\n",
    "        start_h, start_min = start_time.split(':')[0], start_time.split(':')[-1]\n",
    "        end_h, end_min = end_time.split(':')[0], end_time.split(':')[-1]\n",
    "        \n",
    "        api_url = 'https://api.boerse-frankfurt.de/data/tick_data?limit=2500&offset=0&isin='+ \\\n",
    "                str(self.isin)+'&mic=XETR&minDateTime='+today_date+'T'+str(start_h)+'%3A'+ \\\n",
    "                str(start_min)+'%3A00.000Z&maxDateTime='+today_date+'T'+str(end_h)+'%3A'+ \\\n",
    "                str(end_min)+'%3A00.000Z'\n",
    "        \n",
    "        req = requests.get(api_url)\n",
    "        json_data = req.json()['ticks']\n",
    "        df_ticker = pd.DataFrame(json_data)\n",
    "        df_ticker.set_index('time', inplace=True)\n",
    "        return df_ticker\n",
    "    \n",
    "    \n",
    "    def get_price(self):\n",
    "        api_url = 'https://api.boerse-frankfurt.de/data/price_information?isin=' + \\\n",
    "        str(self.isin) + '&mic=XETR'\n",
    "        \n",
    "        req = requests.get(api_url, stream=True)\n",
    "        for line in req.iter_lines():\n",
    "            if line:\n",
    "                price = float(json.loads(line[5:].decode('utf-8')).get('lastPrice'))\n",
    "                return price             \n",
    "       \n",
    "    \n",
    "    def price_stream(self):\n",
    "        api_url = 'https://api.boerse-frankfurt.de/data/price_information?isin=' + \\\n",
    "        str(self.isin) + '&mic=XETR'\n",
    "        \n",
    "        req = requests.get(api_url, stream=True)\n",
    "        for line in req.iter_lines():     \n",
    "            if line:\n",
    "                price = float(json.loads(line[5:].decode('utf-8')).get('lastPrice'))\n",
    "                yield price\n",
    "        \n",
    "    \n",
    "    def get_bid_ask(self):\n",
    "        api_url = 'https://api.boerse-frankfurt.de/data/bid_ask_overview?isin=' + \\\n",
    "        str(self.isin) + '&mic=XETR'\n",
    "        \n",
    "        req = requests.get(api_url, stream=True)\n",
    "        for line in req.iter_lines(decode_unicode=True):\n",
    "            if line:\n",
    "                json_data = json.loads(line[5:]).get('data')[0]\n",
    "                \n",
    "                bid_price = float(json_data.get('bidPrice'))\n",
    "                ask_price = float(json_data.get('askPrice'))\n",
    "                return bid_price, ask_price\n",
    "            \n",
    "            \n",
    "    def bid_ask_stream(self):\n",
    "        api_url = 'https://api.boerse-frankfurt.de/data/bid_ask_overview?isin=' + \\\n",
    "        str(self.isin) + '&mic=XETR'\n",
    "        \n",
    "        req = requests.get(api_url, stream=True)\n",
    "        for line in req.iter_lines(decode_unicode=True):\n",
    "            if line:\n",
    "                json_data = json.loads(line[5:]).get('data')[0]\n",
    "                \n",
    "                bid_price = float(json_data.get('bidPrice'))\n",
    "                ask_price = float(json_data.get('askPrice'))\n",
    "                yield [bid_price, ask_price ]       \n",
    "              \n",
    "\n",
    "    def get_fee(self):\n",
    "        api_url = 'https://api.boerse-frankfurt.de/data/fees_etp?isin=' + str(self.isin)\n",
    "        req = requests.get(api_url, stream=True)        \n",
    "        total_expense_perc = req.json().get('totalExpensePercent')\n",
    "        return total_expense_perc                   \n",
    "       "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Historical prices for a single asset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 204,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>open</th>\n",
       "      <th>close</th>\n",
       "      <th>high</th>\n",
       "      <th>low</th>\n",
       "      <th>turnoverPieces</th>\n",
       "      <th>turnoverEuro</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2020-01-02</th>\n",
       "      <td>19.442</td>\n",
       "      <td>19.484</td>\n",
       "      <td>19.568</td>\n",
       "      <td>19.442</td>\n",
       "      <td>36747.0</td>\n",
       "      <td>717800.38</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-03</th>\n",
       "      <td>19.366</td>\n",
       "      <td>19.378</td>\n",
       "      <td>19.384</td>\n",
       "      <td>19.312</td>\n",
       "      <td>15210.0</td>\n",
       "      <td>294449.00</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-06</th>\n",
       "      <td>19.228</td>\n",
       "      <td>19.234</td>\n",
       "      <td>19.246</td>\n",
       "      <td>19.112</td>\n",
       "      <td>79552.0</td>\n",
       "      <td>1525667.13</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-07</th>\n",
       "      <td>19.378</td>\n",
       "      <td>19.408</td>\n",
       "      <td>19.430</td>\n",
       "      <td>19.354</td>\n",
       "      <td>24226.0</td>\n",
       "      <td>469576.97</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-08</th>\n",
       "      <td>19.268</td>\n",
       "      <td>19.436</td>\n",
       "      <td>19.436</td>\n",
       "      <td>19.258</td>\n",
       "      <td>20883.0</td>\n",
       "      <td>402873.16</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "              open   close    high     low  turnoverPieces  turnoverEuro\n",
       "date                                                                    \n",
       "2020-01-02  19.442  19.484  19.568  19.442         36747.0     717800.38\n",
       "2020-01-03  19.366  19.378  19.384  19.312         15210.0     294449.00\n",
       "2020-01-06  19.228  19.234  19.246  19.112         79552.0    1525667.13\n",
       "2020-01-07  19.378  19.408  19.430  19.354         24226.0     469576.97\n",
       "2020-01-08  19.268  19.436  19.436  19.258         20883.0     402873.16"
      ]
     },
     "execution_count": 204,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "asset_prices = Asset('DE000A0H08D2').hist_prices(start_date='2020-01-01', end_date='2020-03-01')\n",
    "asset_prices.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Historical closing prices of multiple assets"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 205,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>IE00B42Z5J44</th>\n",
       "      <th>DE000A0H08D2</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>date</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2020-01-01</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-02</th>\n",
       "      <td>50.264</td>\n",
       "      <td>19.484</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-03</th>\n",
       "      <td>49.888</td>\n",
       "      <td>19.378</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-06</th>\n",
       "      <td>49.988</td>\n",
       "      <td>19.234</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-01-07</th>\n",
       "      <td>50.346</td>\n",
       "      <td>19.408</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "            IE00B42Z5J44  DE000A0H08D2\n",
       "date                                  \n",
       "2020-01-01           NaN           NaN\n",
       "2020-01-02        50.264        19.484\n",
       "2020-01-03        49.888        19.378\n",
       "2020-01-06        49.988        19.234\n",
       "2020-01-07        50.346        19.408"
      ]
     },
     "execution_count": 205,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "start_date, end_date = '2020-01-01', '2020-03-01'\n",
    "df = pd.DataFrame(pd.bdate_range(start_date, end_date, freq='B'), columns=['date'])\n",
    "df.set_index('date', inplace=True)\n",
    "\n",
    "isin_list = ['IE00B42Z5J44', 'DE000A0H08D2']\n",
    "\n",
    "for isin in isin_list:\n",
    "    df[isin] = Asset(isin).hist_prices(start_date, end_date)['close']\n",
    "    \n",
    "df.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Most recent price of an asset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 194,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "40.858\n"
     ]
    }
   ],
   "source": [
    "price = Asset('IE00B42Z5J44').get_price()\n",
    "print(price)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Price data live stream of an asset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 206,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "15.718\n"
     ]
    }
   ],
   "source": [
    "for price in Asset('DE000A0H08D2').price_stream():\n",
    "    print(price)\n",
    "    break"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Most recent bid and ask price"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 210,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "40.952 41.02\n"
     ]
    }
   ],
   "source": [
    "bid_price, ask_price = Asset('IE00B42Z5J44').get_bid_ask()\n",
    "print(bid_price, ask_price)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Spread data live stream of an asset"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 217,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "41.01 41.064\n"
     ]
    }
   ],
   "source": [
    "for spread in Asset('IE00B42Z5J44').bid_ask_stream():\n",
    "    bid_price, ask_price = spread[0], spread[1]\n",
    "    print(bid_price, ask_price)\n",
    "    break"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Today's ticker data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 123,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>price</th>\n",
       "      <th>turnover</th>\n",
       "      <th>turnoverInEuro</th>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>time</th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "      <th></th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>2020-03-24T12:01:51+01:00</th>\n",
       "      <td>41.111</td>\n",
       "      <td>79.0</td>\n",
       "      <td>3247.769</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-03-24T12:01:50+01:00</th>\n",
       "      <td>41.107</td>\n",
       "      <td>1565.0</td>\n",
       "      <td>64332.455</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-03-24T12:01:48+01:00</th>\n",
       "      <td>41.106</td>\n",
       "      <td>97.0</td>\n",
       "      <td>3987.282</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-03-24T12:01:22+01:00</th>\n",
       "      <td>41.049</td>\n",
       "      <td>2992.0</td>\n",
       "      <td>122818.608</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2020-03-24T11:57:53+01:00</th>\n",
       "      <td>41.000</td>\n",
       "      <td>5000.0</td>\n",
       "      <td>205000.000</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "                            price  turnover  turnoverInEuro\n",
       "time                                                       \n",
       "2020-03-24T12:01:51+01:00  41.111      79.0        3247.769\n",
       "2020-03-24T12:01:50+01:00  41.107    1565.0       64332.455\n",
       "2020-03-24T12:01:48+01:00  41.106      97.0        3987.282\n",
       "2020-03-24T12:01:22+01:00  41.049    2992.0      122818.608\n",
       "2020-03-24T11:57:53+01:00  41.000    5000.0      205000.000"
      ]
     },
     "execution_count": 123,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "ticker = Asset('IE00B42Z5J44').get_ticker(start_time='09:34', end_time='17:00')\n",
    "ticker.head()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Total expense percentage of a fund or ETF"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 207,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "0.64\n"
     ]
    }
   ],
   "source": [
    "fee = Asset('IE00B42Z5J44').get_fee()\n",
    "print(fee)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
